<?php
namespace app\common\model;
use think\Model;
use think\Loader;
use think\Validate;
use app\publictool\controller\PublicTool;
use think\Cache;
class Base extends Model{

   protected $table='';

   protected static  $inputData;

   protected static  $cacheTag='base'; //缓存的名称,关闭使用缓存直接使用false

   protected static  $autoRefreshCache=true; //增加，修改，删除，自动更新缓存

   protected static  $autoPushCreateTime = false; //自动添加时间

   protected static  $autoPushUpdateTime = false; //自动添加修改时间

   //静态初始化内容
   protected static function init(){
     //注册插入前的功能
     static::beforeInsert(function($self){
        //是否自动加入修改时间
        if($self::$autoPushCreateTime){
          //加入当前修改的时间戳
          $self->data('create_time',time());
          //加入当前的修改时间
          $self->data('last_update_time',time());
        }
     });

     //插入后自动刷新缓存
     self::afterInsert(function($self){
       //检测插入操作自动刷新缓存,刷新带有标签的内容
       //此种方式可以实现插入即更新缓存不插入，即不更新缓存
       if($self::$autoRefreshCache){

          Cache::clear(self::$cacheTag);

       }
     });

     //修改后自动刷新缓存
     self::afterUpdate(function($self){
         //是否自动加入修改时间
         if(self::$autoPushUpdateTime){
           //加入当前的修改时间
           $self->data('last_update_time',time());
         }
       //自动刷新缓存
         if(self::$autoRefreshCache){
           Cache::clear(self::$cacheTag);
         }
     });

   }


   /**
    * [infoOfCache protected]
    * @param  array  $info [查询的信息]
    * @return [type]       [array返回数组信息]
    */
   protected static function infoOfCache($info=[],$refresh=false){
      if(true === $refresh){
          self::cacheRefresh();
      }
      if(is_array($info)){
        $key   = empty($info['cache_key'])? null : $info['cache_key'];
        $expir = empty($info['expir'])? config('cache.expire') :$info['expir'];
        $cacheTag = self::$cacheTag;
        $where = empty($info['where'])? abort(-0100,'搜索条件不能为空') : $info['where'];
        $limit = empty($info['limit'])? 'find' : $info['limit'];
        $page  = empty($info['page'])? 1 : $info['page'];
        $order = empty($info['order'])? 'create_time desc' : $info['order'];
        $field = empty($info['field'])? false : $info['field'];
        $response = [];
        if($limit == 'find'){
          $result = self::where($where)->cache($key,$expir,$cacheTag)->order($order)->field($field)->find();
          $response = empty($result)? [] : $result->toArray();//->toArray();
        }else{
          $result = self::where($where)->cache($key,$expir,$cacheTag)->order($order)->field($field)->select();
          $response = empty($result)? [] : collection($result)->toArray();
        }
        //如果返回真的话清除缓存
      }
      //查询是否为对象
      if(is_object($info)){
         $result = $info->cache(null,config('cache.expire'),static::$cacheTag)->select();
         $response = empty($result)? [] : collection($result)->toArray();
      }

      if(count($response) > 0){
        if (true == static::cachePolicy($response)){ //刷新缓存的策略
            self::cacheRefresh();
        }
      }
      return $response;
   }

   /**
    * [cacheRefresh 刷新缓存]
    * @return [void] [void]
    */
   protected static function cacheRefresh(){
        Cache::clear(static::$cacheTag);
   }

   /**
    * [cachePolicy 缓存策略]
    * @param  [array] $response [查询到的缓存内容]
    * @return [void]           [true|false]
    */
   protected static function cachePolicy(&$response){
      return false;
   }



  /**
   * [infoOfNoCache description]
   * @param  array  $info [查询的信息以数组形式体现]
   * @return [type]       [array返回数组信息]
   */
   protected static function infoOfNoCache($info=[]){

   }

   /**
    * [final 设置返回的数据]
    * @param $input 设置 $inputData的数据
    * @var [type]
    */
   final public static function setInputData($key=null,$value=null){
      if(is_array($key)){
          static::$inputData = $key;
          return;
      }
          static::$inputData[$key] = $value;
   }
   /**
    * [final 获取输入的数据]
    * @var [type]
    */
   final public static function getInputData($key=null){
      return PublicTool::getInputData(static::$inputData,$key);
   }

   /**
    * [fetchOnce 值寻找一条数据]
    * @return [type] [只寻找一条数据]
    */
   protected static function fetchOnce($data,$condition){

   }


   /**
    * [couSave 保存和修改的配置]
    * @return [type] [保存和修改的配置]
    */
   protected static function couSave($validateParams,$save,$inputData=null){
     $validatePatten =[];
     $validateMessage = [];
     $validate = '';

     if(is_null($inputData)){
        $inputData = self::getInputData();
     }

     if(!empty($validateParams)){
       foreach($validateParams as $val){
         $validatePatten[$val[0]] = $val[1];
         if(gettype($val[1]) == 'object'){
            continue;
         }else{
           if(strpos($val[1],'|')){
               $validateColumns = explode('|',$val[1]);
           }else{
               $validateColumns = $val[1];
           }
           if(is_array($validateColumns)){
             foreach($validateColumns as $validateColumnKey => $validateColumnName){
               //拼接字符串
                if(strpos($val[2],':')){
                    $messageStock = explode(':',$val[2]);
                    if(strpos($messageStock[1],'|')){
                          $messageTemplate = explode('|',$messageStock[1]);
                          $validateMessage[$val[0].'.'.$validateColumnName] = $messageStock[0].$messageTemplate[$validateColumnKey];
                    }else{
                      $validateMessage[$val[0].'.'.$validateColumnName] = $val[2];
                    }
                }else{
                  $validateMessage[$val[0].'.'.$validateColumnName] = $val[2];
                }
             }
           }else{
             $validateMessage[$val[0].'.'.$validateColumns] = $val[2];
           }
         }
       }
     }
     //验证内容的正确性
     $validate = new Validate($validatePatten,$validateMessage);
     //增加自定义验证规则
     static::validateExtend($validate);
     //验证字段的正确性
     if(!$validate->check($inputData)){
        self::validateCheckError($validate);
     }
     $saveStatus = ($save($inputData,get_called_class()));
     if(!$saveStatus){
        self::saveError($saveStatus);
     }
     return true;
   }

    protected static function validateExtend($validate){
        $validate->extend(
          [
            'phone'=>function($val){
                $patten  = '/^(13|14|15|18|17)[0-9]{9}$/';
                dump('检测手机号码');
                return !preg_match($patten,$val)? false : true;
            },
            //验证身份证号码
            'card_id'=>function($val){
                $patten = '/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/';
                return !preg_match($patten,$val)? false : true;
            }
          ]
        );
    }


    /**
     * [validateCheckError 字段验证失败怎么办]
     * @return [type] [description]
     */
    protected static function validateCheckError($info){
        abort(-5,$info->getError());
    }

    /**
     * [saveError 保存失败]
     * @param  [type] $info [description]
     * @return [type]       [description]
     */
    protected static function saveError($info){
        if(!$info && is_numeric($info)){
          abort(-7,'操作失败！');
        }else{
          abort(-6,'保存失败请重试');
        }
    }


  /**
   * [sqlParams 解析sql字符串填写默认的sql筛选项目]
   * @param  [type] $params   [填入的筛选项]
   * @param  array  $default  [默认的sql筛选项目，如果在params中不存在即会获取default中的内容]
   * @param  array  $unparams [过滤的筛选项目]
   * @return [array]           [返回原有的并且返回筛选项目的参数]
   */
   protected static function sqlParams($params,$default=[],$unparams=[]){
      $result = [];
      $field = ['order','field','limit','page'];
      foreach($field as $val){
            if(!array_Key_exists($val,$params) || empty($params[$val])){
                if(in_array($val,$unparams)){
                    continue; //跳过本次循环
                }
                if(array_Key_exists($val,$default)){
                  $result[$val] = $default[$val];
                }
            }else{
              $result[$val] = $params[$val];
            }
      }
      return empty($result)? false : $result;
   }

}
